home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus Special 23
/
AMIGAplus Sonderheft 23 (2000)(Falke)(DE)[!].iso
/
Updates
/
Datatypes
/
JPEG-DT
/
Source
/
dispatcher.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-11-14
|
11KB
|
455 lines
#include <clib/alib_protos.h>
#include <pragma/datatypes_lib.h>
#include <pragma/dos_lib.h>
#include <pragma/exec_lib.h>
#include <pragma/graphics_lib.h>
#include <pragma/intuition_lib.h>
#include <pragma/jpeg_lib.h>
#include <pragma/render_lib.h>
#include <pragma/utility_lib.h>
#include <render/renderhooks.h>
#include <cybergraphx/cybergraphics.h>
#include <datatypes/pictureclass.h>
#include <exec/memory.h>
#include <intuition/icclass.h>
#include <string.h>
#include "class.h"
struct Arg1
{
long *mode,*dither,*depth,*dct,*scale,*quality,*smooth,gray,prog;
};
ULONG SaveJPEG(IClass *cl,Object *obj,dtWrite *msg);
extern Library *SuperClassBase;
void ReadPrefs(Data *data)
{
char *var;
data->mode=1;
data->dither=0;
data->depth=8;
data->dct=0;
data->scale=1;
data->quality=75;
data->smooth=0;
data->gray=0;
data->prog=0;
if(var=(char *)AllocVec(512,0))
{
if(GetVar("ENV:DataTypes/jpeg.prefs",var,512,LV_VAR|GVF_GLOBAL_ONLY)>=0)
{
RDArgs *rdargs;
if(rdargs=(RDArgs *)AllocDosObject(DOS_RDARGS,0))
{
RDArgs *args;
Arg1 para;
rdargs->RDA_Source.CS_Buffer=var;
rdargs->RDA_Source.CS_Length=strlen(var);
rdargs->RDA_Source.CS_CurChr=0;
memset(¶,0,sizeof(Arg1));
if(args=ReadArgs("MODE/A/N,DITHER/A/N,DEPTH/A/N,DCT/A/N,SCALE/A/N,QUALITY/A/N,SMOOTH/A/N,GRAY/S,PROGRESSIVE/S",(long *)¶,rdargs))
{
data->mode=*para.mode;
if(data->mode<0) data->mode=0;
else if(data->mode>1) data->mode=1;
data->dither=*para.dither;
if(data->dither<0) data->dither=0;
else if(data->dither>1) data->dither=1;
data->depth=*para.depth;
if(data->depth<3) data->depth=3;
else if(data->depth>8) data->depth=8;
data->dct=*para.dct;
if(data->dct<0) data->dct=0;
else if(data->dct>2) data->dct=2;
data->scale=*para.scale;
if(data->scale<0) data->scale=0;
else if(data->scale>3) data->scale=3;
data->scale=1<<data->scale;
data->quality=*para.quality;
if(data->quality<1) data->quality=1;
else if(data->quality>100) data->quality=100;
data->smooth=*para.smooth;
if(data->smooth<0) data->smooth=0;
else if(data->smooth>100) data->smooth=100;
data->gray=para.gray;
data->prog=para.prog;
FreeArgs(args);
}
FreeDosObject(DOS_RDARGS,rdargs);
}
}
FreeVec(var);
}
if(SuperClassBase->lib_Version<43) data->mode=0;
}
struct JPEGINFO
{
Object *obj;
RastPort *rp,*trp;
UBYTE *buffer;
UWORD d,gray;
};
static void _getline(UBYTE *scanline,ULONG y,ULONG numb,JPEGINFO *info)
{
if(info->gray) WritePixelLine8(info->rp,0,y,numb,scanline,info->trp);
else
{
ULONG w=numb/3;
if(info->d>8) DoMethod(info->obj,PDTM_WRITEPIXELARRAY,scanline,RECTFMT_RGB,numb,0,y,w,1);
else
{
register ULONG i;
register UBYTE *p1,*p2;
p1=info->buffer+w*y*4;
p2=scanline;
for(i=0;i<w;i++,p1+=4,p2+=3)
{
p1[1]=p2[0];
p1[2]=p2[1];
p1[3]=p2[2];
}
}
}
}
static ULONG getline(register __a0 UBYTE *scanline,register __d0 ULONG line,register __d1 ULONG numb,register __a1 void *userdata)
{
_getline(scanline,line-1,numb,(JPEGINFO *)userdata);
return 0;
}
ULONG Colors2DT(Object *obj,UBYTE *color)
{
UBYTE *cr;
ULONG *cregs,i,num,error=0;
GetDTAttrs(obj,PDTA_NumColors,&num,PDTA_ColorRegisters,&cr,PDTA_CRegs,&cregs,TAG_END);
if(cr&&cregs)
{
if(color)
{
for(i=0;i<num;i++,cr+=3,cregs+=3,color+=4)
{
cr[0]=color[1];
cr[1]=color[2];
cr[2]=color[3];
cregs[0]=cr[0]<<24;
cregs[1]=cr[1]<<24;
cregs[2]=cr[2]<<24;
}
}
else
{
for(i=0;i<num;i++,cr+=3,cregs+=3)
{
cr[0]=i;
cr[1]=i;
cr[2]=i;
cregs[0]=i<<24;
cregs[1]=cregs[0];
cregs[2]=cregs[0];
}
}
}
else error=ERROR_NO_FREE_STORE;
return error;
}
static void FillBMHD(Object *obj,BitMapHeader *bh,ULONG w,ULONG h,ULONG depth)
{
bh->bmh_Left=0;
bh->bmh_Top=0;
bh->bmh_Width=w;
bh->bmh_Height=h;
bh->bmh_PageWidth=w;
bh->bmh_PageHeight=h;
bh->bmh_Depth=depth;
bh->bmh_Compression=cmpByteRun1;
bh->bmh_XAspect=0;
bh->bmh_YAspect=0;
}
static void GetMode(Object *obj,BitMapHeader *bh,Data *data)
{
ULONG mode;
mode=BestModeID(
BIDTAG_NominalWidth,bh->bmh_PageWidth,BIDTAG_NominalHeight,bh->bmh_PageHeight,
BIDTAG_DesiredWidth,bh->bmh_Width,BIDTAG_DesiredHeight,bh->bmh_Height,
BIDTAG_Depth,bh->bmh_Depth,
BIDTAG_DIPFMustNotHave,DIPF_IS_DUALPF|DIPF_IS_PF2PRI|DIPF_IS_HAM|DIPF_IS_EXTRAHALFBRITE,TAG_END);
SetDTAttrs(obj,0,0,PDTA_ModeID,mode,TAG_END);
if(bh->bmh_Depth<=8) SetDTAttrs(obj,0,0,PDTA_NumColors,1<<bh->bmh_Depth,TAG_END);
}
static ULONG GetBody_Gray(JPEGDecHandle *jph,BitMapHeader *bh,BitMap *bm,Data *data)
{
ULONG error=0;
UBYTE *buffer;
RastPort rp;
if(buffer=(UBYTE *)AllocBufferFromJPEG(jph,JPG_ScaleDenom,data->scale,TAG_END))
{
if(!DecompressJPEG(jph,JPG_DestRGBBuffer,buffer,JPG_ScaleDenom,data->scale,JPG_DCTMethod,data->dct,TAG_END))
{
Chunky2BitMap(buffer,0,0,bh->bmh_Width,bh->bmh_Height,bm,0,0,TAG_END);
}
else error=ERROR_NO_FREE_STORE;
FreeJPEGBuffer(buffer);
}
else
{
BitMap *tbm;
if(tbm=AllocBitMap(bh->bmh_Width,1,8,BMF_MINPLANES,bm))
{
RastPort trp;
InitRastPort(&rp);
InitRastPort(&trp);
rp.BitMap=bm;
trp.BitMap=tbm;
JPEGINFO info={0,&rp,&trp,0,8,1};
if(DecompressJPEG(jph,JPG_DecompressHook,getline,JPG_DecompressUserData,&info,JPG_ScaleDenom,data->scale,JPG_DCTMethod,data->dct,TAG_END)) error=ERROR_NO_FREE_STORE;
FreeBitMap(tbm);
}
else error=ERROR_NO_FREE_STORE;
}
return error;
}
static ULONG GetBody_RGB(Object *obj,JPEGDecHandle *jph,BitMapHeader *bh,Data *data)
{
ULONG error=0;
UBYTE *buffer;
if(buffer=(UBYTE *)AllocBufferFromJPEG(jph,JPG_ScaleDenom,data->scale,TAG_END))
{
if(!DecompressJPEG(jph,JPG_DestRGBBuffer,buffer,JPG_ScaleDenom,data->scale,JPG_DCTMethod,data->dct,TAG_END))
{
DoMethod(obj,PDTM_WRITEPIXELARRAY,buffer,RECTFMT_RGB,bh->bmh_Width*3,0,0,bh->bmh_Width,bh->bmh_Height);
}
else error=ERROR_NO_FREE_STORE;
FreeJPEGBuffer(buffer);
}
else
{
JPEGINFO info={obj,0,0,0,24,0};
if(DecompressJPEG(jph,JPG_DecompressHook,getline,JPG_DecompressUserData,&info,JPG_ScaleDenom,data->scale,JPG_DCTMethod,data->dct,TAG_END)) error=ERROR_NO_FREE_STORE;
}
return error;
}
static ULONG GetBody_RGB8(Object *obj,JPEGDecHandle *jph,BitMapHeader *bh,BitMap *bm,Data *data)
{
ULONG error=0;
UBYTE *rgb;
if(rgb=(UBYTE *)AllocVec(4*bh->bmh_Width*bh->bmh_Height,MEMF_CLEAR))
{
JPEGINFO info={obj,0,0,rgb,bh->bmh_Depth,0};
if(!DecompressJPEG(jph,
JPG_DecompressHook,getline,
JPG_DecompressUserData,&info,
JPG_ScaleDenom,data->scale,
JPG_DCTMethod,data->dct,
TAG_END))
{
APTR rmh;
if(rmh=CreateRMHandler(RND_MemType,RMHTYPE_POOL,TAG_END))
{
ULONG *palette;
if(palette=CreatePalette(RND_RMHandler,rmh,TAG_END))
{
APTR hst;
if(hst=CreateHistogram(RND_RMHandler,rmh,TAG_END))
{
if(AddRGBImage(hst,(ULONG *)rgb,bh->bmh_Width,bh->bmh_Height,TAG_END)==ADDH_SUCCESS)
{
ULONG numc;
GetDTAttrs(obj,PDTA_NumColors,&numc,TAG_END);
if(ExtractPalette(hst,palette,numc,TAG_END)==EXTP_SUCCESS)
{
UBYTE *chunky;
if(chunky=(UBYTE *)AllocVec(bh->bmh_Width*bh->bmh_Height,0))
{
if(Render((ULONG *)rgb,bh->bmh_Width,bh->bmh_Height,chunky,palette,RND_DitherMode,data->dither,TAG_END)==REND_SUCCESS)
{
UBYTE *color;
if(color=(UBYTE *)AllocVec((1<<bh->bmh_Depth)*4,0))
{
ExportPalette(palette,color,TAG_END);
if(!(error=Colors2DT(obj,color))) Chunky2BitMap(chunky,0,0,bh->bmh_Width,bh->bmh_Height,bm,0,0,TAG_END);
FreeVec(color);
}
else error=ERROR_NO_FREE_STORE;
}
else error=ERROR_NO_FREE_STORE;
FreeVec(chunky);
}
else error=ERROR_NO_FREE_STORE;
}
else error=ERROR_NO_FREE_STORE;
}
else error=ERROR_NO_FREE_STORE;
DeleteHistogram(hst);
}
else error=ERROR_NO_FREE_STORE;
DeletePalette(palette);
}
else error=ERROR_NO_FREE_STORE;
DeleteRMHandler(rmh);
}
else error=ERROR_NO_FREE_STORE;
}
else error=ERROR_NO_FREE_STORE;
FreeVec(rgb);
}
else error=ERROR_NO_FREE_STORE;
return error;
}
static ULONG GetPicture(IClass *cl,Object *obj)
{
ULONG error=0;
long err;
BPTR file;
BitMapHeader *bh;
GetDTAttrs(obj